package com.woniu.consumer;

import com.rabbitmq.client.Channel;
import com.woniu.entity.Order;
import com.woniu.entity.OrderItem;
import com.woniu.mapper.OrderItemMapper;
import com.woniu.mapper.OrderMapper;
import com.woniu.service.ProductService;
import com.woniu.util.ConstantUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.List;

@Component
@Slf4j
public class CheckOrderConsumer {

    @Resource
    private OrderMapper orderMapper;
    @Resource
    private OrderItemMapper orderItemMapper; // 用于查订单项
    @Resource
    private ProductService productService;   // 用于恢复库存（含缓存处理）
    // 最大重试次数（首次 + 重试）
    private static final int MAX_RETRY_TIMES = 3;
    // 每次重试间隔：5秒
    private static final long RETRY_DELAY_MILLIS = 5000;

    @RabbitListener(queues = {ConstantUtil.RABBIT_QUEUE_CHECK_ORDER_STATUS})
    public void consume(String msg, Channel channel, Message message) {
        try {
            log.info("延迟队列收到消息：{}", msg);
            String orderId;
            try {
                orderId = msg.trim();
            } catch (NumberFormatException e) {
                log.error("消息格式错误，无法解析为订单ID: {}", msg);
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                return;
            }

            // ===== 开始重试查询 =====
            Order order = null;
            int attempt = 0;

            while (attempt < MAX_RETRY_TIMES) {
                attempt++;
                log.debug("第 {} 次查询订单，orderId={}", attempt, orderId);
                order = orderMapper.getById(orderId);


                if (order != null) {
                    break; // 查到就跳出循环
                }

                // 如果不是最后一次尝试，就等待后继续
                if (attempt < MAX_RETRY_TIMES) {
                    log.warn("第 {} 次查询失败，订单不存在，{}ms 后重试", attempt, RETRY_DELAY_MILLIS);
                    Thread.sleep(RETRY_DELAY_MILLIS); // 同步等待
                }
            }

            // ===== 重试结束，判断结果 =====
            if (order == null) {
                log.error("重试 {} 次后，订单仍未创建，可能已异常或消息错误。orderId={}", MAX_RETRY_TIMES, orderId);
                // 可选：发送告警、记录监控表等
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                return;
            }

            // ===== 订单存在，判断状态 =====
            if (order.getStatus() != 2) {
                log.info("检测到未支付订单，正在关闭... orderId={}", orderId);

                // 🔁 先恢复库存，再关闭订单（避免状态已变）
                boolean restoreSuccess = restoreStockForOrder(orderId);
                if (!restoreSuccess) {
                    log.warn("订单 {} 库存恢复失败或部分失败，但仍继续关闭订单", orderId);
                    // 注意：即使恢复失败，也要关闭订单，避免死循环
                }

                // 关闭订单
                order.setStatus(5); // 已取消（超时未支付）
                orderMapper.update(order);
                log.info("订单已成功关闭（超时） orderId={}", orderId);
            } else {
                log.info("订单状态已变更，无需关闭 orderId={}, status={}", orderId, order.getStatus());
            }

            // 确认消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);

        } catch (InterruptedException e) {
            // 被中断（如系统关闭），记录日志
            Thread.currentThread().interrupt();
            log.error("订单取消任务被中断", e);
            // 不 requeue，避免无限重试
            try {
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            } catch (IOException ex) {
                log.error("ACK 失败", ex);
            }
        } catch (Exception e) {
            log.error("处理延迟消息时发生异常", e);
            try {
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
            } catch (IOException ex) {
                log.error("basicNack 失败", ex);
            }
        }
    }

    /**
     * 恢复订单商品库存
     */
    private boolean restoreStockForOrder(String orderId) {
        try {
            // 1. 查询订单项
            List<OrderItem> orderItems = orderItemMapper.findOrderDetail(orderId);
            if (orderItems == null || orderItems.isEmpty()) {
                log.warn("订单 {} 没有订单项，无需恢复库存", orderId);
                return true;
            }

            boolean allSuccess = true;

            // 2. 遍历每个商品，增加库存
            for (OrderItem item : orderItems) {
                Integer productId = item.getProductId();
                Integer buyNum = item.getBuyNum();

                if (productId == null || buyNum == null || buyNum <= 0) continue;

                try {
                    // 使用 ProductService 增加库存（自动处理缓存）
                    boolean success = productService.increaseStock(productId, buyNum);
                    if (success) {
                        log.info("✅ 商品ID={} 库存恢复成功：+{} 件", productId, buyNum);
                    } else {
                        log.error("❌ 商品ID={} 库存恢复失败", productId);
                        allSuccess = false;
                    }
                } catch (Exception e) {
                    log.error("恢复商品ID={}库存时异常", productId, e);
                    allSuccess = false;
                }
            }

            return allSuccess;
        } catch (Exception e) {
            log.error("恢复订单 {} 库存时发生异常", orderId, e);
            return false;
        }
    }
}